#ifndef _BVHTREE_H_
#define	_BVHTREE_H_

//#pragma once
//#include <boost/function.hpp>

//////////////////////////////////////////////////////////////////////////
// Templated class the will create a BVH out of any type of Bounding Volume, 
// as long as the Bounding Volume follows the AABB's interface.
//////////////////////////////////////////////////////////////////////////

template <typename BVType>
class BVTree
{
private:	// Members 	
	//////////////////////////////////////////////////////////////////////////
	// Stores the BV for that node, parent and children pointers
	//////////////////////////////////////////////////////////////////////////
	struct TreeNode
	{
		BVType *pBV;
		TreeNode *pLeftNode;
		TreeNode *pRightNode;
		TreeNode(){ 
			pLeftNode = pRightNode = NULL;
			pBV = NULL;
		}
	};

public:		// Members

	// Root of the tree
	TreeNode *pRoot;
	int m_nNumNode;
	int m_nMaxDepth;

	////////////////////////////////////////////////////////////////////////////
	//// This is the function that will be called on the current BV as we iterate 
	//// through the tree. The prototype of the function is:
	////  "bool func(const BVType *current);"
	//// Treat this just like a funciton pointer! It is just typedef'ed
	////
	//// Parameters
	//// const BVNode *node	- the current node in the traversal
	////
	//// bool					- if true, keep traversing deeper, 
		////						  if false, prune that branch
	////
	//// Notes:
	//// Example of a function that has the correct prototype:
	//// bool DrawBVTrangles(const BVType *current) { current->DrawTrangles(); return true; }
	////////////////////////////////////////////////////////////////////////////
	//typedef boost::function<bool (const BVType *current)> TraverseFunc;

private:	// Methods
	//////////////////////////////////////////////////////////////////////////
	// I only want a BVTree to be made from the contructor below
	//////////////////////////////////////////////////////////////////////////
	BVTree(void);
	
	//////////////////////////////////////////////////////////////////////////
	// This is a recursive function that takes the BV of the current node,
	// splits it into its children, inserting them into the tree, and calls 
	// itself on the children.
	//
	// Parameters
	// BVNode *current	- the current node in the tree that we are building
	//
	// Notes:	This function will be calling the BV's GetTriangles and Split 
	//			functions.  So makes sure you implement them according to the 
	//			BV inteface.
	//////////////////////////////////////////////////////////////////////////
	void BuildTree(TreeNode *current,size_t leafSz, int currentDepth);

public:		// Methods
	
	//////////////////////////////////////////////////////////////////////////
	// Creates a BVTree using the triangles passed in and the leaf size as the 
	// terminating condition
	//
	// Parameters
	// vector<Triangle> tris - the triangles to build the BVTree out of
	// size_t leafSz	- the amount of triangles to terminate tree generation
	//
	// Notes: 
	//	- The tree will be resposible for cleaning up "rt"'s memory
	//	- From this constructor the tree will build itself by calling the 
	//	  buildTree function
	//////////////////////////////////////////////////////////////////////////
	BVTree(std::vector<Triangle> tris, size_t leafSz);
	
	//////////////////////////////////////////////////////////////////////////
	// Cleans up the dynamic memory that the tree used
	//////////////////////////////////////////////////////////////////////////
	~BVTree(void);	

	//////////////////////////////////////////////////////////////////////////
	// This is a recursive function that traverses the tree depth first.
	//
	// Parameters
	// const BVNode *node	- the current node in the traversal
	// TraverseFunc func	- the function to be called on the BV of the 
	//						  current BVNode
	//
	// Notes:
	//	- if the Traverse func returns true, keep traversing deeper, if false,
	//	  prune that branch
	//////////////////////////////////////////////////////////////////////////
	void Traverse(const TreeNode *node);/* ,TraverseFunc func);*/

	void DeleteAllNodes(  TreeNode * node);

};
#include "BVTree.hpp"
#endif
